#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <sqlite3.h>
#import <QuartzCore/QuartzCore.h>
#import "../LockInfo/Plugin.h"

#import "FWPlugin.h"
#import "FWDetailListView.h"


static CGFloat iPhoneCellInset = 10;
static CGFloat iPhoneCellBorder = 10;

static CGFloat iPadCellInset = 45;
static CGFloat iPadCellBorder = 10;

static CGFloat iconPadding = 8;

static CGFloat const kNavButtonWidth = 44.0;


NSString* const FWDetailListViewFieldTitle = @"title";
NSString* const FWDetailListViewFieldMessage = @"message";
NSString* const FWDetailListViewFieldValue = @"value";
NSString* const FWDetailListViewFieldNoBold = @"nobold";
NSString* const FWDetailListViewFieldSize = @"size";
NSString* const FWDetailListViewFieldIcon = @"icon";
NSString* const FWDetailListViewFieldLines = @"lines";
NSString* const FWDetailListViewFieldColor = @"color";
NSString* const FWDetailListViewFieldBGColor = @"bgcolor";
NSString* const FWDetailListViewFieldProgress = @"progress";
NSString* const FWDetailListViewFieldSwitch = @"switch";
NSString* const FWDetailListViewFieldSelected = @"selected";

static CGSize const ProgressBarSize = CGSizeMake(150, 9);
static CGSize const iPadSwitchSize = CGSizeMake(250, 27);
static CGSize const iPhoneSwitchSize = CGSizeMake(100, 27);


//obj respondsToSelector:@selector(userInterfaceIdiom
@implementation FWDetailListView

@synthesize delegate, index, application, list, view, navControl, caption, navBar, sections;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

- (id)initWithFrame:(CGRect)r list:(NSArray*)l index:(NSInteger)i caption:(NSString*)capt application:(FWApplication*)app delegate:(id<FWDetailListViewDelegate>)d
{
    if (self = [super initWithFrame:r]) {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        self.autoresizesSubviews = YES;
        
        self.list = l;
        self.delegate = d;
        self.application = app;
        self.caption = capt;
        [self buildPreview:r];
        self.index = i;
    }
    
    return self;
}

- (id)initWithFrame:(CGRect)r list:(NSArray*)l index:(NSInteger)i application:(FWApplication*)app delegate:(id<FWDetailListViewDelegate>)d
{
    if (self = [self initWithFrame:r list:l index:i caption:@"" application:app delegate:d]) {
    }
    
    return self;
}

- (void)dealloc
{
    [delegate release];
    [list release];
    [view release];
    [application release];
    [navControl release];
    [sections release];
    [navBar release];
    [caption release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Attribute access and support

- (void)setCaption:(NSString*)newCaption
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    [caption release];
    caption = localize(bundle, newCaption);
    [caption retain];
    
    if (self.navBar) {
        UINavigationItem* nav = self.navBar.topItem;
        nav.title = caption;
    }
}

- (void)setIndex:(NSInteger)i
{
    index = i;

    if ([self.list count] > 1) {
        [self.navControl setEnabled:(i > 0) forSegmentAtIndex:0];
        [self.navControl setEnabled:(i < ((int)[self.list count] - 1)) forSegmentAtIndex:1];
    }

    self.sections = [delegate dataForIndex:i list:self.list database:self.application.databasePath application:self.application];

    NSRange range = [caption rangeOfString:@"%i"];
    if (range.location != NSNotFound) {
        UINavigationItem* nav = self.navBar.topItem;
        nav.title = [NSString stringWithFormat:caption, i+1, [self.list count]];
    }

    [self reloadData:YES];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Main window layout

- (void)buildPreview:(CGRect)rect
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    
    UIBarButtonItem* doneBtn = [[[UIBarButtonItem alloc]
                                 initWithTitle:localize(bundle, @"Detail/Button/Done")
                                 style:UIBarButtonItemStyleBordered 
                                 target:self
                                 action:@selector(doneClicked)] autorelease];
    
    UIBarButtonItem* cancelBtn = [[[UIBarButtonItem alloc]
                                   initWithTitle:localize(bundle, @"Detail/Button/Cancel")
                                   style:UIBarButtonItemStyleBordered 
                                   target:self
                                   action:@selector(cancelClicked)] autorelease];

    UIBarButtonItem* selectBtn = [[[UIBarButtonItem alloc]
                                   initWithTitle:localize(bundle, @"Detail/Button/Select")
                                   style:UIBarButtonItemStyleBordered 
                                   target:self
                                   action:@selector(selectClicked)] autorelease];
    
    UIImage* btnUp = [UIImage imageWithContentsOfFile:@"/Applications/MobileMail.app/arrowup.png"];								  
    UIImage* btnDown = [UIImage imageWithContentsOfFile:@"/Applications/MobileMail.app/arrowdown.png"];								  
    self.navControl = [[[UISegmentedControl alloc]
                        initWithItems:
                        [NSArray arrayWithObjects:
                         btnUp,
                         btnDown,
                         nil]] autorelease];
    
    if ((btnUp == nil) || (btnDown == nil))
        self.navControl = [[[UISegmentedControl alloc]
                            initWithItems:
                            [NSArray arrayWithObjects:
//                             localize(bundle, @"Detail/Button/Up"),
//                             localize(bundle, @"Detail/Button/Down"),
                             @"U", @"D",
                             nil]] autorelease];
    
    self.navControl.segmentedControlStyle = UISegmentedControlStyleBar;
    self.navControl.momentary = YES;
    [self.navControl setWidth:kNavButtonWidth forSegmentAtIndex:0];
    [self.navControl setWidth:kNavButtonWidth forSegmentAtIndex:1];
    
    [self.navControl addTarget:self
                        action:@selector(navigateClicked:)
              forControlEvents:UIControlEventValueChanged];
    
    UIBarButtonItem* navBtn = [[[UIBarButtonItem alloc] initWithCustomView:self.navControl] autorelease];
    
    const CGFloat toolbarHeight = 44;
    CGRect navBarFrame = CGRectMake(0, 0, rect.size.width, toolbarHeight);
    CGRect taskBarFrame = CGRectMake(0, rect.size.height - toolbarHeight, rect.size.width, toolbarHeight);
    CGRect scrollFrame = CGRectMake(0, navBarFrame.size.height, rect.size.width, rect.size.height - taskBarFrame.size.height - navBarFrame.size.height);
    
    UINavigationBar* nav = [[[UINavigationBar alloc] initWithFrame:navBarFrame] autorelease];
    nav.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    nav.barStyle = UIBarStyleBlackOpaque;
    self.navBar = nav;
    
    UINavigationItem* navItem = [[[UINavigationItem alloc] initWithTitle:self.caption] autorelease];

    if ([delegate respondsToSelector:@selector(cancelClicked:sections:)]) {
        navItem.leftBarButtonItem = cancelBtn;

        if ([delegate respondsToSelector:@selector(doneClicked:sections:)])
            navItem.rightBarButtonItem = doneBtn;
        else if ([delegate respondsToSelector:@selector(selectClicked:sections:)])
            navItem.rightBarButtonItem = selectBtn;
    }
    else if ([delegate respondsToSelector:@selector(doneClicked:sections:)])
            navItem.leftBarButtonItem = doneBtn;

    if ([self.list count] > 1)
        navItem.rightBarButtonItem = navBtn;

    [nav setItems:[NSArray arrayWithObjects:navItem, nil] animated:NO];
    [self addSubview:nav];
         
//#ifdef DEBUG
//    UIToolbar* task = [[[UIToolbar alloc] initWithFrame:taskBarFrame] autorelease];
//    task.autoresizingMask = UIViewAutoresizingFlexibleWidth;
//    task.barStyle = UIBarStyleBlackOpaque;
//    task.items = [NSArray arrayWithObjects:
//                  flexibleSpace,
//                  nil];
//    [self addSubview:task];
//#else
    scrollFrame.size.height += taskBarFrame.size.height;
//#endif
    
    UITableView* tableView = [[UITableView alloc] initWithFrame:scrollFrame style:UITableViewStyleGrouped];
    tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    tableView.autoresizesSubviews = YES;
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.allowsSelection = NO;
    
    [self addSubview:tableView];
    self.view = tableView;
    
    [tableView release];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Tableview section information

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self.sections count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSArray* sect = [self.sections objectAtIndex:section];
    return [sect count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return nil;
}

- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == 0)
        return 4.0;
    else
        return 1.0;
}

- (CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section
{
    return 2.0;
}

- (UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section
{
    return [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] autorelease];
}

- (UIView*)tableView:(UITableView*)tableView viewForFooterInSection:(NSInteger)section
{
    return [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] autorelease];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Tableview element layout

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    BOOL iPad = (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
    CGFloat cellInset = iPad ? iPadCellInset : iPhoneCellInset;
    CGFloat cellBorder = iPad ? iPadCellBorder : iPhoneCellBorder;
    CGFloat width = tableView.frame.size.width - 2 * (cellInset + cellBorder);
    int section = indexPath.section;
    NSArray* sect = [self.sections objectAtIndex:section];
    
    int row = indexPath.row;
    NSDictionary* elem = [sect objectAtIndex:row];
    
    NSString* title = [elem objectForKey:FWDetailListViewFieldTitle];
    NSString* message = [elem objectForKey:FWDetailListViewFieldMessage];
    NSString* value = [elem objectForKey:FWDetailListViewFieldValue];
    NSNumber* nobold = [elem objectForKey:FWDetailListViewFieldNoBold];
    NSNumber* swtch = [elem objectForKey:FWDetailListViewFieldSwitch];
    NSNumber* progress = [elem objectForKey:FWDetailListViewFieldProgress];
    NSNumber* size = [elem objectForKey:FWDetailListViewFieldSize];
    if (size == nil)
        size = [NSNumber numberWithFloat:[UIFont labelFontSize]];
    
    if (progress || swtch || (value == nil) || ([value length] == 0)) {
        UIImage* newIcon = [elem objectForKey:FWDetailListViewFieldIcon];
        CGFloat iconWidth = (newIcon != nil) ? (newIcon.size.width + iconPadding): 0;
        
        CGSize constraint = CGSizeMake(width - iconWidth, MAXFLOAT);

        if (progress)
            constraint.width -= ProgressBarSize.width;
        else if (swtch) 
            constraint.width -= iPad ? iPadSwitchSize.width : iPhoneSwitchSize.width;

        // If we have a message then use it as the basis for the title size
        if (message)
            title = message;
        
        UIFont* font = nil;
        if (nobold == nil)
            font = [UIFont boldSystemFontOfSize:size.floatValue];
        else
            font = [UIFont systemFontOfSize:size.floatValue];
        CGSize titleSize = [title sizeWithFont:font
                             constrainedToSize:constraint
                                 lineBreakMode:UILineBreakModeWordWrap];
        
        return titleSize.height + cellBorder * 2;
    }
    else {
        CGSize titleSize = [title sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont labelFontSize]]];
        CGSize constraint = CGSizeMake(width - titleSize.width - 6, MAXFLOAT);
        CGSize detailSize = [value sizeWithFont:[UIFont systemFontOfSize:size.floatValue] 
                              constrainedToSize:constraint
                                  lineBreakMode:UILineBreakModeWordWrap];
        
        if (titleSize.height > detailSize.height)
            return titleSize.height + cellBorder * 2;
        else
            return detailSize.height + cellBorder * 2;
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Tableview element access

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    BOOL iPad = (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
    int section = indexPath.section;
    NSArray* sect = [self.sections objectAtIndex:section];
    
    int row = indexPath.row;
    NSDictionary* elem = [sect objectAtIndex:row];
    
    NSString* title = [elem objectForKey:FWDetailListViewFieldTitle];
    NSString* value = [elem objectForKey:FWDetailListViewFieldValue];
    UIImage* icon = [elem objectForKey:FWDetailListViewFieldIcon];
    NSNumber* nobold = [elem objectForKey:FWDetailListViewFieldNoBold];
    NSNumber* lines = [elem objectForKey:FWDetailListViewFieldLines];

    NSNumber* size = [elem objectForKey:FWDetailListViewFieldSize];
    if (size == nil)
        size = [NSNumber numberWithFloat:[UIFont labelFontSize]];

    UIColor* bgcolor = [elem objectForKey:FWDetailListViewFieldBGColor];
    if (!bgcolor)
        bgcolor = [UIColor whiteColor];
    
    static NSString *MyIdentifier = @"PITodoPreview";
    static NSInteger messageTag = 100;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
                                       reuseIdentifier:MyIdentifier] autorelease];

        UILabel* message = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
        message.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
        message.tag = messageTag;
        message.textAlignment = UITextAlignmentCenter;
        message.backgroundColor = [UIColor clearColor];
        message.hidden = YES;
        [cell.contentView addSubview:message];
    }

    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.accessoryView = nil;
    cell.backgroundColor = bgcolor;
    [[cell.contentView viewWithTag:messageTag] setHidden:YES];

    if (NSNumber* progress = [elem objectForKey:FWDetailListViewFieldProgress]) {
        UIProgressView *progressBar = [[[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault] autorelease];
        progressBar.progress = [progress floatValue];
        CGRect size = progressBar.frame;
        size.size.width = iPad ? iPadSwitchSize.width : iPhoneSwitchSize.width;
        progressBar.frame = size;
        cell.accessoryView = progressBar;
    }
    else if (NSNumber* swtch = [elem objectForKey:FWDetailListViewFieldSwitch]) {
        UISwitch *switcher = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
        switcher.on = [swtch boolValue];
        switcher.tag = section * 100 + row;
        [switcher addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
        cell.accessoryView = switcher;
    }
    else if (NSNumber* selected = [elem objectForKey:FWDetailListViewFieldSelected]) {
        if ([selected boolValue])
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }        
    else if (NSString* message = [elem objectForKey:FWDetailListViewFieldMessage]) {
        UILabel* label = (UILabel*)[cell.contentView viewWithTag:messageTag];
        CGFloat cellInset = iPad ? iPadCellInset : iPhoneCellInset;
        CGFloat cellBorder = iPad ? iPadCellBorder : iPhoneCellBorder;

        label.font = [UIFont boldSystemFontOfSize:[size floatValue]];
        CGFloat width = tableView.frame.size.width - 2 * (cellInset + cellBorder);
        CGFloat height = [label.font leading]; 

        label.frame = CGRectMake(cellBorder, cellBorder, width, height);
        label.hidden = NO;
        label.text = message;
        
        UIColor* color = [elem objectForKey:FWDetailListViewFieldColor];
        if (color == nil)
            color = [UIColor darkTextColor];
        
        label.textColor = color;      
    }

    if (nobold == nil)
        cell.textLabel.font = [UIFont boldSystemFontOfSize:size.floatValue];
    else
        cell.textLabel.font = [UIFont systemFontOfSize:size.floatValue];
    
    cell.textLabel.text = title;
    cell.detailTextLabel.font = [UIFont systemFontOfSize:size.floatValue];
    cell.detailTextLabel.text = value;
    cell.imageView.image = icon;
    
    if ((value != nil) && ([value length] > 0)) {
        if (lines == nil) {
            cell.textLabel.numberOfLines = 1;
            cell.detailTextLabel.numberOfLines = 0;
        }
        else {
            cell.textLabel.numberOfLines = lines.intValue;
            cell.detailTextLabel.numberOfLines = lines.intValue;
        }			
        cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
        cell.textLabel.textColor = [UIColor darkTextColor];
    }
    else {
        if (lines == nil) {
            cell.textLabel.numberOfLines = 0;
            cell.detailTextLabel.numberOfLines = 1;
        }
        else {
            cell.textLabel.numberOfLines = lines.intValue;
            cell.detailTextLabel.numberOfLines = lines.intValue;
        }			
        cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
        
        if (nobold != nil)
            cell.textLabel.textColor = cell.detailTextLabel.textColor;
        else {
            UIColor* color = [elem objectForKey:FWDetailListViewFieldColor];
            if (color == nil)
                color = [UIColor darkTextColor];
            cell.textLabel.textColor = color;
        }
    }
    
    return cell;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Animation and eye-candy

- (void)reloadData:(BOOL)animated
{
    [self.view reloadData];
    [self.view scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];

    if (animated) {
        CATransition *animation = [CATransition animation];
        [animation setType:kCATransitionFade];
        [animation setDuration:0.4];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [animation setFillMode: @"extended"];

        [[self.view layer] addAnimation:animation forKey:@"reloadAnimation"];
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Command button callbacks

- (void)cancelClicked
{
    if ([delegate cancelClicked:self.application sections:self.sections])
        [self.application.plugin.plugin dismissPreview];
}

- (void)doneClicked
{
    if ([delegate doneClicked:self.application sections:self.sections])
        [self.application.plugin.plugin dismissPreview];
}

- (void)selectClicked
{
    if ([delegate selectClicked:self.application sections:self.sections])
        [self.application.plugin.plugin dismissPreview];
}

- (void)switchChanged:(id)sender
{
    UISwitch* sw = (UISwitch*)sender;
    NSInteger section = (int)(sw.tag / 100);
    NSInteger row = (sw.tag % 100);
    
    NSArray* sect = [self.sections objectAtIndex:section];
    NSMutableDictionary* element = [sect objectAtIndex:row];
    
    [element setObject:[NSNumber numberWithBool:sw.on] forKey:FWDetailListViewFieldSwitch];
}

- (void)navigateClicked:(id)sender
{
    UISegmentedControl *control = (UISegmentedControl *)sender;
    if ([control selectedSegmentIndex] == 0)
        self.index = self.index - 1;
    else
        self.index = self.index + 1;
}

@end
